#include "pro_ext.h"

void FAR reduce_byref(ParamBlk FAR *parm)
{
	Value val;
	char deduplicatedChar = ' ';
	BOOL alltrimMode = TRUE, charWasFound;
	char FAR *pString, *pRead, *pWrite;

	_Load(&parm->p[0].loc, &val);
	if (val.ev_type != 'C')
		_Error(9); // "Data type mismatch"
	if (val.ev_length == 0)
		return; // empty string

	if (parm->pCount > 1 && parm->p[1].val.ev_length > 0)
		deduplicatedChar = ((char FAR *) _HandToPtr(parm->p[1].val.ev_handle))[0]; // take first character.

	if (parm->pCount > 2 && parm->p[2].val.ev_length == 0)
		alltrimMode = FALSE;

	charWasFound = alltrimMode;

	pString = _HandToPtr(val.ev_handle);
	pRead = pString;
	pWrite = pString;
	while (pRead < pString + val.ev_length)
	{
		if (*pRead == deduplicatedChar)
		{
			if (!charWasFound)
			{
				// copy first char and set flag to remove all subsequent
				charWasFound = TRUE;
				*pWrite++=*pRead;
			}
		}
		else
		{
			// good char
			charWasFound = FALSE;
			*pWrite++=*pRead;
		}
		pRead++;
	}

	if (alltrimMode && charWasFound && pWrite > pString)
		pWrite--;// last symbol must be removed even if it is single

	_SetHandSize(val.ev_handle, pWrite-pString);
	val.ev_length = pWrite-pString;

	_Store(&parm->p[0].loc, &val);
	// We need to free the handle that we created with _LOAD()
	_FreeHand(val.ev_handle);
}

void FAR reduce_byval(ParamBlk FAR *parm)
{
	Value val;
	char deduplicatedChar = ' ';
	BOOL alltrimMode = TRUE, charWasFound;
	char FAR *pString, *pRead, *pWrite;

	val = parm->p[0].val;
	if (val.ev_length == 0)
	{
		_RetVal(&val);
		return; // empty string
	}

	if (parm->pCount > 1 && parm->p[1].val.ev_length > 0)
		deduplicatedChar = ((char FAR *) _HandToPtr(parm->p[1].val.ev_handle))[0]; // take first character.

	if (parm->pCount > 2 && parm->p[2].val.ev_length == 0)
		alltrimMode = FALSE;

	charWasFound = alltrimMode;

	pString = _HandToPtr(val.ev_handle);
	pRead = pString;
	pWrite = pString;
	while (pRead < pString + val.ev_length)
	{
		if (*pRead == deduplicatedChar)
		{
			if (!charWasFound)
			{
				// copy first char and set flag to remove all subsequent
				charWasFound = TRUE;
				*pWrite++=*pRead;
			}
		}
		else
		{
			// good char
			charWasFound = FALSE;
			*pWrite++=*pRead;
		}
		pRead++;
	}

	if (alltrimMode && charWasFound && pWrite > pString)
		pWrite--;// last symbol must be removed even if it is single

	val.ev_length = pWrite-pString;
	_RetVal(&val);
}

FoxInfo myFoxInfo[] =
{
	{"REDUCE_R", (FPFI) reduce_byref, 3, "R.C.L"},
	{"REDUCE_V", (FPFI) reduce_byval, 3, "C.C.L"}
};

FoxTable _FoxTable =
{
    (FoxTable FAR *)0, sizeof(myFoxInfo) / sizeof(FoxInfo), myFoxInfo
};
